/*
 * DrawerWebDeso.java
 *
 * Copyright (c) 2006 Computer-Aided Integrated Systems Laboratory, 
 * St. Petersburg Institute for Informatics and Automation RAS http://cais.lisa.iias.spb.su
 */

package guislicer;

import matching.UnicodeVertexStringer;
import matching.UnicodeEdgeStringer;
import matching.GraphCreator;

import edu.uci.ics.jung.utils.UserData;
import edu.uci.ics.jung.graph.Graph;
import edu.uci.ics.jung.graph.impl.SparseGraph;
import edu.uci.ics.jung.graph.impl.SparseVertex;
import edu.uci.ics.jung.graph.impl.UndirectedSparseEdge;
import edu.uci.ics.jung.graph.Edge;
import edu.uci.ics.jung.graph.Element;
import edu.uci.ics.jung.graph.Vertex;

import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JPanel;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;

import edu.uci.ics.jung.algorithms.importance.*;

import edu.uci.ics.jung.utils.MutableDouble;
import edu.uci.ics.jung.utils.UserData;

import edu.uci.ics.jung.graph.Graph;
import edu.uci.ics.jung.graph.Edge;
import edu.uci.ics.jung.graph.Element;
import edu.uci.ics.jung.graph.Vertex;
import edu.uci.ics.jung.graph.ArchetypeVertex;
import edu.uci.ics.jung.graph.decorators.DefaultToolTipFunction;
import edu.uci.ics.jung.graph.decorators.EdgeShape;
import edu.uci.ics.jung.graph.decorators.PickableEdgePaintFunction;
import edu.uci.ics.jung.graph.decorators.EllipseVertexShapeFunction;
import edu.uci.ics.jung.graph.decorators.PickableVertexPaintFunction;
import edu.uci.ics.jung.graph.decorators.VertexIconAndShapeFunction;
import edu.uci.ics.jung.graph.decorators.VertexStringer;
import edu.uci.ics.jung.graph.impl.UndirectedSparseEdge;
import edu.uci.ics.jung.graph.impl.DirectedSparseEdge;
import edu.uci.ics.jung.graph.impl.DirectedSparseGraph;
import edu.uci.ics.jung.graph.impl.DirectedSparseVertex;
import edu.uci.ics.jung.visualization.DefaultGraphLabelRenderer;
import edu.uci.ics.jung.visualization.FRLayout;
import edu.uci.ics.jung.visualization.GraphZoomScrollPane;
import edu.uci.ics.jung.visualization.PluggableRenderer;
import edu.uci.ics.jung.visualization.ShapePickSupport;
import edu.uci.ics.jung.visualization.VisualizationViewer;
import edu.uci.ics.jung.visualization.control.CrossoverScalingControl;
import edu.uci.ics.jung.visualization.control.DefaultModalGraphMouse;
import edu.uci.ics.jung.visualization.control.ModalGraphMouse;
import edu.uci.ics.jung.visualization.control.ScalingControl;

import java.util.ArrayList;
import java.util.Map;


/** Draws classes (and attributes and relations between them) taken from 
 * WebDeso database via Jung editor GUI.
 */
public class DrawerWebDeso {

    /** the visual component and renderer for the graph */
    VisualizationViewer vv;
    
    /** Creates a new instance of DrawerWebDeso */
    public DrawerWebDeso() {
    }
    
    /** Whether to enable visual effects (e.g. draw edge labels) if true,
     * skip all visual functions if only calculations to be done. */
    public boolean enable_visual;
    
    UnicodeVertexStringer   u_vertexstringer;
    UnicodeEdgeStringer     u_edgestringer;
    
    public Graph    graph1;
    public Graph    graph2;
    public Graph    graph12;

    //public List<Vertex>    v_graph1;
    //public List<Vertex>    v_graph2;
    
    static final String[] labels1 = {
            // 0-4 vertices
            "Thing",        // 0
            "Supplier",     // 1
            "Hardware",     // 2
            "Furniture",    // 3
            "Mobile-Phone", // 4
        };
    int[][] edges1 = { {0,1}, {1,2}, {1,3}, {2,4}};
    
    static final String[] labels2 = {
            // 5-9 vertices
            "Thing",        // 5
            "Provider",     // 6
            "Computer",     // 7
            "Furniture"     // 8
        };
    
    int[][] edges2 = { {0,1}, {1,2}, {1,3}, {2,3}};
    
    
    private void loadImages(Vertex[] vertices, Map imageMap) {
        
        ImageIcon icon_class = null;
        ImageIcon icon_attr = null;
        try {
            icon_class  = new ImageIcon(getClass().getResource("/class.png"));
            icon_attr   = new ImageIcon(getClass().getResource("/attr.png"));
        } catch(Exception ex) {
            System.err.println("You need class_icons.jar in your classpath to see the class, attribute icons.");
        }
        
        for(Vertex v:vertices) {
            imageMap.put(v,icon_class);
        }
    }
        
    public void draw(Graph graph)
    {   
        Vertex[] v = (Vertex[])(graph.getVertices()).toArray(new Vertex[0]);
        
        PluggableRenderer pr = new PluggableRenderer();
        u_vertexstringer = new UnicodeVertexStringer();
        pr.setVertexStringer(u_vertexstringer);
        pr.setVertexPaintFunction(new PickableVertexPaintFunction(pr, Color.lightGray, Color.white,  Color.yellow));
        pr.setGraphLabelRenderer(new DefaultGraphLabelRenderer(Color.cyan, Color.cyan));
        VertexIconAndShapeFunction dvisf =
            new VertexIconAndShapeFunction(new EllipseVertexShapeFunction());
        pr.setVertexShapeFunction(dvisf);
        pr.setVertexIconFunction(dvisf);
        loadImages(v, dvisf.getIconMap());
        vv =  new VisualizationViewer(new FRLayout(graph), pr);
        vv.setPickSupport(new ShapePickSupport());
        pr.setEdgeShapeFunction(new EdgeShape.QuadCurve());
        vv.setBackground(Color.white);
        
        u_edgestringer = new UnicodeEdgeStringer ();
        pr.setEdgeStringer(u_edgestringer);
        //pr.setEdgePaintFunction(new PickableEdgePaintFunction(pr, Color.black, Color.cyan));

        // add my listener for ToolTips
        vv.setToolTipFunction(new DefaultToolTipFunction());
        
        // create a frome to hold the graph
        final JFrame frame = new JFrame();
        Container content = frame.getContentPane();
        final GraphZoomScrollPane panel = new GraphZoomScrollPane(vv);
        content.add(panel);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        
        final ModalGraphMouse gm = new DefaultModalGraphMouse();
        vv.setGraphMouse(gm);
        
        final ScalingControl scaler = new CrossoverScalingControl();

        JButton plus = new JButton("+");
        plus.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                scaler.scale(vv, 1.1f, vv.getCenter());
            }
        });
        JButton minus = new JButton("-");
        minus.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                scaler.scale(vv, 0.9f, vv.getCenter());
            }
        });

        JCheckBox lo = new JCheckBox("Show Node Labels");
        lo.addItemListener(new ItemListener(){
            public void itemStateChanged(ItemEvent e) {
                u_vertexstringer.setShowLabels(e.getStateChange() == ItemEvent.SELECTED);
                vv.repaint();
            }
        });
        lo.setSelected(true);
        
        JCheckBox loe = new JCheckBox("Show Edge Labels");
        loe.addItemListener(new ItemListener(){
            public void itemStateChanged(ItemEvent e) {
                u_edgestringer.setShowLabels(e.getStateChange() == ItemEvent.SELECTED);
                vv.repaint();
            }
        });
        loe.setSelected(true);
        
        JPanel controls = new JPanel();
        controls.add(plus);
        controls.add(minus);
        controls.add(lo);
        controls.add(loe);
        controls.add(((DefaultModalGraphMouse) gm).getModeComboBox());
        content.add(controls, BorderLayout.SOUTH);

        frame.pack();
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        
        DrawerWebDeso dwd = new DrawerWebDeso();
        dwd.enable_visual = true;
        
        Graph g1 = GraphCreator.createGraph(  GraphCreator.labels1, GraphCreator.edges1);
        Graph g12 =GraphCreator.addGraph(g1,  GraphCreator.labels2, GraphCreator.edges2);
        
        //Graph g3 = join(Graph g1, Graph g2);
        dwd.draw(g12);
        int i = 1;
        while(i>0) {
            i = 1;
        };
    }

}
